package com.idlecode.service;

import cn.hutool.core.util.StrUtil;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.PersistentStateComponent;
import com.intellij.openapi.components.Service;
import com.intellij.openapi.components.State;
import com.intellij.openapi.components.Storage;
import org.apache.commons.io.ByteOrderMark;
import org.apache.commons.io.input.BOMInputStream;
import org.jetbrains.annotations.NotNull;

import javax.swing.*;
import java.io.*;

/**
 * @program: IdleCode
 * @description 缓存代码格式配置信息
 * @author: rongjuwei
 * @create: 2024-02-06 09:37
 **/
@Service
@State(name = "IdleCodeRemoveBom", storages = @Storage(value = "IdleCodeRemoveBom.xml"))
public final class RemoveBomService implements PersistentStateComponent<RemoveBomService> {

    private String removeBomPath;

    public static RemoveBomService getInstance() {
        return ApplicationManager.getApplication().getService(RemoveBomService.class);
    }

    /**
     * 持久化配置
     */
    @Override
    public RemoveBomService getState() {
        return this;
    }

    /**
     * 加载配置
     */
    @Override
    public void loadState(@NotNull RemoveBomService state) {
        this.removeBomPath = state.removeBomPath != null ? state.removeBomPath : "";
    }

    /**
     * 找不到配置文件时加载
     */
    @Override
    public void noStateLoaded() {
        System.out.println("找不到配置文件");
        removeBomPath = "";
    }

    private static final ByteOrderMark[] BOM_MARKS = {
            ByteOrderMark.UTF_8,
            ByteOrderMark.UTF_16LE,
            ByteOrderMark.UTF_16BE,
            ByteOrderMark.UTF_32LE,
            ByteOrderMark.UTF_32BE
    };
    public static int count;

    /**
     * 清除文件的 BOM，并将内容写回文件
     */
    public static void removeBOMFromFile(File file, JTextArea textArea) throws Exception {
        if (!file.getName().endsWith(".java")) {
            return;
        }

        File tempFile = new File(file.getAbsolutePath() + ".tmp");

        try (BOMInputStream bomIn = BOMInputStream.builder()
                .setInputStream(new FileInputStream(file))
                .setByteOrderMarks(BOM_MARKS)
                .get();
             OutputStream out = new FileOutputStream(tempFile)) {

            // 检查是否存在 BOM
            if (bomIn.hasBOM()) {
                count++;
                // 在 textArea 中添加文件路径
                if (StrUtil.isBlank(textArea.getText())) {
                    textArea.append(file.getAbsolutePath());
                } else {
                    textArea.append("\n");
                    textArea.append(file.getAbsolutePath());
                }
            }

            // 读取文件内容并写入临时文件
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = bomIn.read(buffer)) != -1) {
                out.write(buffer, 0, bytesRead);
            }
        }

        // 删除原文件并重命名临时文件
        if (!file.delete() || !tempFile.renameTo(file)) {
            throw new IOException("Failed to replace the original file with the modified file.");
        }
    }

    public static void processDirectory(File dir, JTextArea textArea) throws Exception {
        if (dir.isDirectory()) {
            File[] files = dir.listFiles();
            if (files != null) {
                for (File file : files) {
                    if (file.isDirectory()) {
                        processDirectory(file, textArea);
                    } else {
                        removeBOMFromFile(file, textArea);
                    }
                }
            }
        }
    }

    public String getRemoveBomPath() {
        return removeBomPath;
    }

    public void setRemoveBomPath(String removeBomPath) {
        this.removeBomPath = removeBomPath;
    }
}
